-
Notifications
You must be signed in to change notification settings - Fork 523
MapQuest improvement #840
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MapQuest improvement #840
Conversation
|
Thank you for this PR. |
|
The custom implementation of a query is only to make it easier to use. It will work fine with a reqular query as well, as I wrote in the Readme.md |
|
I would be way happier without the custom implementation. That would also avoid the changes in Common |
|
I am sorry that you do not like the custom implementation of Or are you just opposed to having two The additional one should work fine as a replacement for all the cases where the original one may be used. Without the new |
|
It is a bit unfortunate that the interface I guess changing it to use interfaces is the "right" thing to do, but that will be a huge BC break. Removing the The only other alternative I can see is to declare that the Query classes are set in stone, and we can have no suggested changes or development on the Query classes. I think that would be a bit unfortunate thing to do. |
|
Hi @Nyholm what/when will be the next step? |
Nyholm
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the reminder. I gave this another quick review.
About the massive changes in MapQuest: You are the expert here. I do not know much about that provider and the API.
About the changes in Common: I would be really happy if they are kept to a minimum.
| /** | ||
| * @param string $text | ||
| */ | ||
| private function __construct(string $text) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need to override a private constructor? Why not override the create function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seemed to me to be logical that when the class is not final any more, child classes should be free to do a different __construct. But I can do as you say, and override the create function instead, no problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to keep the changes to the GeocodeQuery to a strict minimum.
src/Provider/MapQuest/MapQuest.php
Outdated
| return $this->executeQuery($url); | ||
| private function extractAddressFromQuery(CommonGeocodeQuery $query) | ||
| { | ||
| if ($query instanceof GetAddressInterface) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for my lack of understanding. Why do we need this check?
Dont we get the address either way? The way you implemented getAddress is:
public function getAddress()
{
return $this->getData(static::DATA_KEY_ADDRESS);
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was my attempt at future proofing the code a bit.
This way for any GeocodeQuery object that implements the GetAddressInterface will just call the getAddess method, and we do not care where it is stored. If I could have changed the common GeocodeQuery class I would have left it at that.
The line
return $query->getData(GeocodeQuery::DATA_KEY_ADDRESS);
is just a fallback for if you are using a regular GeocodeQuery that does not implement the GetAddressInterface.
I think it is better to depend on interfaces instead of depending on a known constant in a specific class.
I implemented getAddress the way I did to have max interoparability with the common GeocodeQuery class, so that a programmer did not have to use the mapquest version of the GeocodeQuery class.
| /** | ||
| * @var array | ||
| */ | ||
| private $data = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need to modify the scope of $data? You could just introduce a new property on Geocoder\Provider\MapQuest\GeocodeQuery, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My goal was that the new GeocodeQuery class could be a drop in and exchangeable with the old one. If I introduce a new property, I would also have to reimplement the withData method right?
It seemed easier for me to do it this way. If you agree to remove the final keyword, why cannot all properties be protected?
| * | ||
| * @var string | ||
| */ | ||
| private $text; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this needed? If you overwrite withText then there is no need for changing this to protected, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I can overwrite all the methods to avoid changing the properties in the base class to from private to protected. But I thought the proper way was to change the visibilty of the properties, not to duplicate the code in the methods?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you change the visibility like this we risk that someone writes code to make this mutable. I would like you not to change this.
| /** | ||
| * @author Tobias Nyholm <tobias.nyholm@gmail.com> | ||
| */ | ||
| final class GeocodeQuery implements Query |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This hurts a little but Im fine with it =)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for that. I am glad that you will at least allow this.
| return $this->parseHttpResponse($response, $url); | ||
| } | ||
|
|
||
| protected function parseHttpResponse(ResponseInterface $response, string $url): string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are welcome.
| return $this->text; | ||
| } | ||
|
|
||
| protected function formatAddress(Location $address): string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function seams to violate the single responsibility principle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is that?
It is a protected method required by the above getText() method.
Should not a query containing an address have a method to convert that address to a one line text query, so that the query can be used also in other providers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only meant as a default value for the text of the query, and will not be called if the user calls GoecodeQuery::withText him/her self to set the text portion of the query.
(Btw. "seams" = sömmar, "seems"= verkar)
| return new self($address); | ||
| } | ||
|
|
||
| public function getAddress() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is only use internally. It could be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the implementation of the GetAddressInterface. It makes is possible to get the address out of the Query without knowing anything about how it is stored in the Query.
What do you mean it is only used internally? Other (user land) code code also have use of the ease of calling getAddress on the Query, if they want to get the addres from the query.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, since this GecodeQuery has a createFromAddress method, is it not natural that it then also has getAddress method?
This reminds me that may be I should have an withAddress method as well, in case the user wants to add the address or "change" it later. (Yes, I know it is an immutable object that does not change :-)
What do you think, should I add the method withAddress?
|
|
||
| public static function createFromAddress(Location $address): self | ||
| { | ||
| return new self($address); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just do:
$foo = new self('');
return $foo->withData(static::DATA_KEY_ADDRESS], $address);There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a bit more ineffecient, as it will create two objects instead of one, and then leave the first one to be garbage collected.
But yes, that is a valid way to do it if the methods in the base class cannot be changed to be protected instead of private.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another thing is that $foo = new self('') will not work, it would trigger the exception InvalidArgument('Geocode query cannot be empty').
And if I have to put something in the $text property, what should it be? Since you want me to remove the formatAddress method I would be stuck with a GeocodeQuery that would return something weird if it is used in another provider that calls getText.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is really not that inefficient. We are talking optimization on less than duoble quotes vs single quotes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, forget my inefficency arguments then. Please respond to the other points I raised.
|
Thank you for your review. I will wait for your response before I push a new set of changes. |
|
@Nyholm any updates on this? I am still waiting for your comments. |
|
@Nyholm Have you been on vacation or something? Please continue the conversation so we can land this PR. |
|
@Nyholm if we are going to change the Do you agree with the above statement? Or do you have any reason I am not aware of for wanting to keep it all as private? |
Nyholm
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I've been to vacation. =)
I really like the changes you do in the provider. The review process of this PR is is harder because you want to push many changes to the GeocodeQuery class. I find it hard to see scenarios where you really have to update that class. Most of your arguments are "it is easier"...
Try you restrict yourself to not update the common objects. You may send another PR with these changes later.
| * | ||
| * @var string | ||
| */ | ||
| private $text; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you change the visibility like this we risk that someone writes code to make this mutable. I would like you not to change this.
| /** | ||
| * @param string $text | ||
| */ | ||
| private function __construct(string $text) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to keep the changes to the GeocodeQuery to a strict minimum.
|
Ok, If you will please accept #849 that I have made with the minimal changes to the common files, I will then after that make the necessary changes to this PR to reflect that. Hopefully we can then move this PR forward. |
|
@Nyholm for me to make the tests pass you need to tag a new version of https://github.com/geocoder-php/provider-integration-tests |
400434b to
4112648
Compare
4112648 to
97a0ff6
Compare
|
@Nyholm plase make a new version tag on the geocoder-php/provider-integration-tests repository so that I can update the composer.lock files so this will do the tests properly. You will also need to merge #849 and add a tag to that before this PR can show green on all tests. |
|
@Nyholm, have you gone on vacation again? |
|
@Nyholm Are you celebrating Norways national day today? |
|
@Nyholm ping |
|
I have complied with everything you have requested, as far as I know. If you want to merge just this pull request, that is fine, then you can ignore #849 Please tell me if there is anything else you need for this to be merged. |
I'll try to be extra clear with what I mean. This is the process I want to follow:
|
|
Does that mean you are backtracking on what we already have discussed? On 13th of April you agreed that I could at least change the Less important are the changes to So, have you changed your stance so to not allow any changes at all in the common classes now? |
|
And again we have this great wall of silence. Is it too much to expect that you are able to respond to me within a day or so? |
Im doing open source work on my free time because I enjoy it. Doing open source is however not the only thing Im doing before and after normal work.
I've not changed my mind. But I feel that you do not really listen when I say "restrict yourself from making changes in common." I know it is possible to add the features you want to add without any changes at all in common (as explained). I want you to see that as well. Since I want to help you to get this merged, I now ask you to not make any changes at all in common since that will ease reviewing and the decisions to merge is not too critical for the rest of the project. You may think Im unfair or unreasonable. I do not want to discuss this anymore, but Im happy to review an updated PR. |
This is not true. It is impossible for me to continue without at least removing the All the other ones I can code around, but not that one. |
|
Shall I go ahead and make the PR so that the removing of the |
|
You are aware that I updated this PR on 14th of May right? And that that update made it only contain 3 small changes to the common files that I thought we were in agreement on? If you were not aware of that, that may be the cause that we are talking past each other? |
|
@Nyholm please answer me so I can go ahead with this PR |
|
Since you do not give any answers, I will just have to assume. I assume then that I reached the correct conclusion when I said "make the PR so that the removing of the final keyword is the only change among the common files". I will go ahead and do just that. |
fcd816b to
b9d4e35
Compare
d95a437 to
c05351a
Compare
|
Ok now everything should be as you want it. Please tag a new version for https://github.com/geocoder-php/provider-integration-tests |
Do I understand right that you want to remove Maybe it's better to improve |
|
@Nyholm argh, removing |
|
After reading original topic, I think you can just make (static) function to create By the way, why does Geocoder have |
|
I've added a PR to your PR: TerjeBr#1 |
|
Ok, I am back from my vacation. Let's see what has happened here. |
|
@unkind wrote:
You are right that it would be better to improve So, this quest of mine to inherit from |
With these changes I find it way easier to merge your PR
|
Ok, I hope this can finally be merged now then. It fails the style guide check, but that was in the changes that @Nyholm introduced, so I guess that is ok. |
|
Ping |
Nyholm
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great. Thank you
This is an improvment to the MapQuest provider, that we talked about in #839
I have tried to stay away from the code in the
Commondirectory, but I could not avoid some small minor changes there to make it all fit together. Hope this will be ok.